package com.controller.sys;


import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.common.base.BaseConstant;
import com.common.base.BaseController;
import com.common.util.LoginUtil;
import com.entity.sys.SysUser;
import com.service.sys.SysSafeService;
import com.service.sys.SysUserService;
import fuhua.com.anno.CheckPermission;
import fuhua.com.anno.Log;
import fuhua.com.util.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 用户信息
 */
@RestController
@RequestMapping("/sys/user")
public class SysUserController extends BaseController<SysUserService,SysUser> {

    @Resource
    private SysSafeService sysSafeService;
    @Value("${filePath}")
    private String path;

    /**
     * 获取当前登录用户信息
     */
    @GetMapping("/getLoginUser")
    public ResultUtil getLoginUserInfo() {
        Map<String,Object> map = new HashMap<>();
        SysUser user = getLoginUser();
        //判断密码是否过了有效期
        if (user.getUpdatePwdTime() == null){
            SysUser byId = service.getById(user.getId());
            user.setUpdatePwdTime(byId.getUpdatePwdTime());
        }
        sysSafeService.getPwdCycle(map,user.getUpdatePwdTime());
        map.put("user",user);
        //查询角色和权限
        map.put("permissions", LoginUtil.getPermList(token(),Convert.toList(String.class,user.getRoleId())));
        return ResultUtil.success(map);
    }

    /**
     * 用户列表
     */
    @GetMapping("/list")
    @CheckPermission(perm = "system:user:view")
    public ResultUtil list(@RequestParam Map<String,String> map) {
        return ResultUtil.success(service.page(map));
    }

    /**
     * 根据id获取用户
     */
    @GetMapping("/getById/{id}")
    public ResultUtil getById(@PathVariable("id")String id) {
        return ResultUtil.success(service.getUser(id,null,null));
    }

    /**
     * 新增
     */
    @Log(title = "新增用户")
    @PostMapping("/insert")
    @CheckPermission(perm = "system:user:add")
    public ResultUtil insert(@RequestBody SysUser user) throws NoSuchAlgorithmException, InvalidKeySpecException {
        if (service.checkUserNameAndPhone(user.getUserName(),user.getPhone(), user.getId())) {
            return ResultUtil.error("用户名或手机号码已存在");
        }
        String password = RSAUtil.decrypt(user.getPassword());// 密码私钥解密
        String salt = EncryptionUtil.generateSalt();
        // 盐值加密
        password = EncryptionUtil.getEncryptedPassword(password, salt);
        user.setSalt(salt);
        user.setPassword(password);
        user.setId(IdUtil.getSnowflakeNextIdStr());
        service.save(user);
        return ResultUtil.success();
    }

    /**
     * 修改用户
     */
    @Log(title = "修改用户")
    @PostMapping("/update")
    @CheckPermission(perm = "system:user:update")
    public ResultUtil update(@RequestBody @Validated SysUser user) {
        if (service.checkUserNameAndPhone(user.getUserName(),user.getPhone(), user.getId())) {
            return ResultUtil.error("用户名或手机号码已存在");
        }
        service.updateById(user);
        if (user.getId().equals(loginId())){
            SysUser userById = service.getUser(user.getId(),null,null);
            service.setDataScope(userById); // 设置用户的数据范围查询条件
            LoginUtil.updateUser(token(),userById); // 更新用户缓存信息
        }
        return ResultUtil.success();
    }

    /**
     * 删除用户
     */
    @Log(title = "删除用户")
    @DeleteMapping("/delete/{id}")
    @CheckPermission(perm = "system:user:delete")
    public ResultUtil delete(@PathVariable("id")String id) {
        String [] ids = Convert.toStrArray(id);
        for (String userId : ids) {
            service.removeById(userId);
        }
        return ResultUtil.success();
    }

    /**
     * 修改密码
     */
    @Log(title = "修改密码")
    @PostMapping("/updatePassword")
    public ResultUtil updatePassword(String oldPassword,String newPassword,String userId) throws InvalidKeySpecException, NoSuchAlgorithmException {
        //私钥解密
        oldPassword = RSAUtil.decrypt(oldPassword);
        newPassword = RSAUtil.decrypt(newPassword);
        if (StrUtil.isEmpty(oldPassword) || StrUtil.isEmpty(newPassword)){
            return ResultUtil.error("数据解密失败");
        }
        if (BaseConstant.initPassword.equals(newPassword)){
            return ResultUtil.error("新密码不可与初始密码相同");
        }
        SysUser user = service.getById(userId);
        //对旧密码进行加密对比
        boolean authenticate = EncryptionUtil.authenticate(oldPassword, user.getPassword(), user.getSalt());
        if (!authenticate){
            return ResultUtil.error("旧密码错误");
        }
        String salt = EncryptionUtil.generateSalt();
        String password = EncryptionUtil.getEncryptedPassword(newPassword, salt);
        UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("password", password);
        updateWrapper.set("salt", salt);
        updateWrapper.set("update_pwd_time", LocalDateTime.now());
        updateWrapper.eq("id",user.getId());
        service.update(updateWrapper);
        return ResultUtil.success();
    }

    /**
     * 上传头像
     */
    @Log(title = "上传头像")
    @PostMapping("/upload")
    public ResultUtil upload(@RequestParam MultipartFile file) throws IOException {
        String dateStr = LocalDateTimeUtil.format(LocalDateTime.now(),"yyyyMMdd-HHmmss");
        String fileName = file.getOriginalFilename();
        String filePath = path + dateStr;
        UpDownUtil.saveFile(file.getInputStream(), filePath, fileName);
        UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("picture",filePath+ "/" + fileName);
        updateWrapper.eq("id", loginId());
        service.update(updateWrapper);
        return ResultUtil.success(filePath+ "/" + fileName);
    }

    @GetMapping("/test1")
    @CheckPermission(perm = {"system:user:view","system:user:add"})
    public ResultUtil test1() {
        return ResultUtil.success("校验用户列表和新增用户权限，通过");
    }

    @GetMapping("/test2")
    @CheckPermission(perm = {"system:user:view","system:user:add"},type = 1)
    public ResultUtil test2() {
        return ResultUtil.success("校验用户列表或新增用户权限，通过");
    }

    @GetMapping("/test3")
    @CheckPermission(role = {"ADMIN","BMFZR"},type = 2)
    public ResultUtil test3() {
        return ResultUtil.success("校验超级管理员和部门负责人角色，通过");
    }

    @GetMapping("/test4")
    @CheckPermission(role = {"ADMIN","BMFZR"},type = 3)
    public ResultUtil test4() {
        return ResultUtil.success("校验超级管理员或部门负责人角色，通过");
    }

    @GetMapping("/test5")
    @CheckPermission(perm = {"system:user:view"},role = {"ADMIN"},type = 4)
    public ResultUtil test5() {
        return ResultUtil.success("校验用户列表权限和超级管理员角色，通过");
    }

    @GetMapping("/test6")
    @CheckPermission(perm = {"system:user:view"},role = {"ADMIN"},type = 5)
    public ResultUtil test6() {
        return ResultUtil.success("校验用户列表权限或超级管理员角色，通过");
    }
}

